package cn.school.pay.service.impl;

import cn.school.common.exception.ApiException;
import cn.school.common.utils.CommonUtil;
import cn.school.common.utils.OkHttpUtil;
import cn.school.common.utils.wx.WeiXinPayCommonUtil;
import cn.school.pay.service.WxPayService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

@Service
@Slf4j
public class WxPayServiceImpl implements WxPayService {


    private String mch_id;


    private String appid_app;


    private String weixin_pay_ip;


    private String wx_pay_callback_notify_url;


    private String domain;


    private String wx_pay_apiUrl;


    private String wx_pay_key;


    @Autowired
    private WeiXinPayCommonUtil weiXinPayCommonUtil;


    @Override
    public Map<Object, Object> wxPayByApp(Map<String, Object> param) throws Exception {
        String wx_pay_randomStr = CommonUtil.getRandomString();
        String goodsName = String.valueOf(param.get("goodsName"));// 商品名称
        String orderNo = String.valueOf(param.get("orderNo"));// 平台订单号
        String actualMoney = String.valueOf(param.get("actualMoney"));// 实付金额(wx单位:分)
        BigDecimal actualMoneyTemp =   new BigDecimal(actualMoney);// 实付金额
        if(goodsName.length()>30){
            goodsName = goodsName.substring(0,30)+"...";
        }
        // 加密，这里只列举必填字段
        SortedMap<String, String> requestmap = new TreeMap<String, String>();
        requestmap.put("body", "南永云商城-" + goodsName);// 商品描述
        requestmap.put("mch_id", mch_id);// 商户号
        requestmap.put("nonce_str", wx_pay_randomStr);// 随机字符串
        requestmap.put("notify_url", domain + wx_pay_callback_notify_url);// 异步回调api
        requestmap.put("appid", appid_app);// APP端应用ID
        requestmap.put("trade_type", "APP"); // 支付类型
        requestmap.put("spbill_create_ip", weixin_pay_ip);// 支付ip
        requestmap.put("out_trade_no", orderNo);// 商品订单号
        requestmap.put("total_fee", (actualMoneyTemp.multiply(new BigDecimal(100))).intValue() + "");// 实付现金

        String characterEncoding = "UTF-8";
        log.info("WeiXinPayServiceImpl payByApp  param:characterEncoding={}",characterEncoding
                + ",requestmap=" + requestmap);
        String sign = createSign(requestmap);
        requestmap.put("sign", sign); // 支付类型
        String xml = weiXinPayCommonUtil.getMapToXML(requestmap);
        // 请求
        log.info("WeiXinPayServiceImpl payByWeb inWeixinPay param:{}", xml);

        String result = OkHttpUtil.httpsRequest(wx_pay_apiUrl, "POST", xml);
        log.info("WeiXinPayServiceImpl payByApp PayCommonUtil.httpsRequest result:{}",result);
        Map<Object, Object> resultMap = weiXinPayCommonUtil.doXMLParse(result);
        String return_code = String.valueOf(resultMap.get("result_code"));
        if ("SUCCESS".equals(return_code)) {
            log.info("WeiXinPayServiceImpl payByApp return_code=" + return_code);
            SortedMap<String, String> payReturnMap = new TreeMap<String, String>();
            payReturnMap.put("partnerid", mch_id);// 商户号
            payReturnMap.put("timestamp", System.currentTimeMillis() / 1000 + "");// 时间戳
            payReturnMap.put("noncestr", wx_pay_randomStr);// 随机字符串
            String prepayid = String.valueOf(resultMap.get("prepay_id")); // 微信返回的支付交易会话ID
            payReturnMap.put("prepayid", prepayid);
            payReturnMap.put("appid", appid_app);// 应用ID
            payReturnMap.put("package", "Sign=WXPay");// 扩展字段
            String sign1 = createSign(payReturnMap);
            payReturnMap.put("paySign", sign1);
            payReturnMap.put("skipPay", "Yes");
            payReturnMap.put("orderNo", orderNo);

            resultMap.put("payReturnMap", payReturnMap);
            log.info("WeiXinPayServiceImpl payByApp payReturnMap: {}" , payReturnMap);
        } else {
            log.error("WeiXinPayServiceImpl payByApp param: request=" + param + ",resultMap={}", resultMap);
            throw new ApiException("WeiXinPayServiceImpl offLinePay param: request=" + param);
        }
        log.info("WeiXinPayServiceImpl payByApp result resultMap={}" ,resultMap);
        return resultMap;
    }

    /**
     * 微信支付签名算法sign
     * @param parameters
     * @return
     */
    public String createSign(SortedMap<String, String> parameters) {
        log.info("WeiXinPayServiceImpl createSign param:parameters:" + parameters);
        StringBuffer sb = new StringBuffer();
        Set es = parameters.entrySet();// 所有参与传参的参数按照accsii排序（升序）
        Iterator it = es.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String k = (String) entry.getKey();
            Object v = entry.getValue();
            if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {
                sb.append(k + "=" + v + "&");
            }
        }
        sb.append("key=" + wx_pay_key);
        String sign = DigestUtils.md5Hex(sb.toString()).toUpperCase();
        log.info("WeiXinPayServiceImpl createSign result sign=" + sign);
        return sign;
    }
}
